<style lang="scss">
.editform {
    .vview-formitem {
        min-height: 32px;
    }
}
</style>
<template>
	<div>
	<Form class="editform clearfix" :model="formData" v-bind="getFormProps" ref="form">
        <Row >
		    <template v-for="(item,index) in formdata" :key="index">
                <Col span='12' v-if="handleVisible(item)" v-bind="getColProps(item)" :key="index">
                    <FormItem v-bind="getFormItemProps(item)" style="position:relative">
                        <Tooltip v-if="item.popper" v-bind="getPopperProps(item)">
                            <Icon class="font-16" type="md-help-circle" style="position: absolute;z-index: 11;right: 5px;top: 10px;" />
                            <compRender v-for="data in getFormChildData(item)" :key="data._key" v-bind="data" />
                        </Tooltip>
                        <compRender v-else v-for="data in getFormChildData(item)" :key="data._key" v-bind="data" />
                    </FormItem>
                </Col>
		    </template>
        </Row>
        <!-- <el-row > -->
            <Col span="24" v-if="$slots.default">
                <slot>
                    <!-- <Button type="error" class="width-50per" @click="cancel">取消</Button>
                    <Button type="primary" class="width-50per" @click="submit">确定</Button>-->
                </slot>
            </Col>
        <!-- </el-row> -->
	</Form>
	<Spin size="large" fix :show="loading"></Spin>
</div>
</template>

<script>
import { h,resolveComponent } from 'vue'
import formmixin from "./formmixin";
export default {
	mixins: [formmixin],
    emits: ['update:modelValue'],
	data() {
		return {
			formData: {},
			newdata:{},
			loading:false,
            labelWidth: 120,
            class: '',
		};
	},
	watch: {
		"$attrs.modelValue": {
			immediate: true,
			deep: true,
			handler(val, old) {
                this.formData = { ...val };
				this.newdata = { ...val };
                // console.log(this.formData,'this.formDatathis.formData33333333333')
                // console.log('formeditFormData', this.formData, val);
			}
		},
	},
	created(){
        this.labelWidth = this.$attrs.labelWidth || 120;
        this.class = this.$attrs.class || ''
		this.loading = true;
	},
	mounted() {
		window.addEventListener('beforeunload', this.beforeunload, false);
		setTimeout(() => {
			this.$refs['form'].resetFields();
			this.formData = this.newdata
		}, 200);
		setTimeout(() => {
			this.loading = false;
		}, 300);

	},
	beforeUnmount() {
		window.removeEventListener('beforeunload', this.beforeunload);
	},
	computed: {
		getFormProps() {
            let rules = {};
            this.formdata.map(item => {
                const { required = true } = { ...item };
                rules[item.key] = [{
                    required: required,
                    message: required ? this.$ct('global.common.fill_required') : "",
                    // trigger: item.tag == "Select" ? "change" : "blur"
                }]
            });
			return {
				// labelWidth: 120,
				rules: {
					// ["*"] : {
					// 	required: true,
					// 	message: this.$ct('global.common.fill_required')
					// },
                    ...rules,
				},
				// ...this.$attrs,
                labelWidth: this.labelWidth,
                class: this.class,
			};
		},
	},
	methods: {
		beforeunload(event) {
			const tip = this.$ct('global.form.warning');
			event = event || window.event;
			event.returnValue = tip;
			return tip;
		},
		setDayFormData(key, val, props){
			console.log(key, val, props)
			if (this.formData[key] === val) return;
			// if(props.type == 'date'){
				this.formData[key] = this.handleDateFormat(val,'yyyy-mm-dd');
				this.$emit("update:modelValue", this.formData);
			// }
			// else if(props.type == 'daterange'){
			// 	this.formData[key] = this.handleDateFormat(val[0],'yyyy-mm-dd')+'~'+this.handleDateFormat(val[1],'yyyy-mm-dd');
			// 	this.$emit("update:modelValue", this.formData);
			// }
		},
		setFormData(key, val) {
            // console.log('formeditFormData', key, val);
            if (this.formData[key] === val) return;
            this.formData[key] = val;
            // console.log(key,val,this.formData,'8888888666666')
			// this.$set(this.formData, key, val);
			this.$emit("update:modelValue", this.formData);
		},
		getPopperProps(item) {
			return {
				content: item.popper,
				gpu: true,
				class: 'width-100per'
			}
		},
		getFormItemProps(item) {
			const { label, langKey, required = true, key, inline, labelWidth, query, formItem } = item;
            return {
				label: langKey ? this.$ct(langKey, { defaultValue: label }) : label,
				inline,
				labelWidth,
				// prop: (required && !query) ? key : undefined,
                prop: !query ? key : undefined,
				...formItem
			}
		},
		getFormChildData(item) {
			let {
				tag,
				props,
				key,
				style,
				children,
				options,
				on: onListeners,
				query,
				class: className,
                // 如果目前的事件转换无法满足，可以直接填入，不要放在on中
                ...otherOptions
				// attach,
			} = item;
			const hasOptions = Array.isArray(options);
			const on = {};
            Object.keys({...onListeners}).forEach(item => {
                let eventName = item;
                // 原生事件需要添加.native标识
                if (eventName.indexOf('.native') != -1) {
                    eventName = `On${eventName.replace('.native', '')}`;
                }
                // iview事件，现在需要onOn-xxx形式才能触发
                else {
                    eventName = `on${eventName[0].toUpperCase()}${eventName.slice(1, eventName.length)}`;
                }
                on[eventName] = onListeners[item].bind(this, this.formData[key]);
            });
            // const on = { ...onListeners };
			// Object.keys(on).forEach(key => {
			// 	on[key] = onListeners[key].bind(this);
			// });
			// 判断是否日期选择
			// console.log(tag)
			if(tag === 'DatePicker'){
				on["onUpdate:modelValue"] = val => this.setDayFormData(key, val, props);
			}else{
				on["onUpdate:modelValue"] = val => this.setFormData(key, val);
			}
			if (key && !query) {
				props = Object.assign({ clearable: true }, props, {
					modelValue: this.formData[key]
				});
                // console.log('ertertert',key)
				// on.input = val => this.setFormData(key, val);
			}
			if (query) {
				return (!key && tag) ? [{
					tag,
					style,
					className: className,
					_key: 0,
					...on,
					attrs: { ...props },
                    ...otherOptions,
					children
				}] : [{
					tag: 'div',
					style,
					_key: 0,
					className: className || 'font-bold text-wrap',
                    ...otherOptions,
                    // innerHTML: this.getValueText(item, this.formData[key])
                    domProps: {
						innerHTML: this.getValueText(item, this.formData[key])
					}
				}]
			}
			if (this.isGroupFormChild(tag)) {
                className = className || 'margin-right-15';
                let result = [{
					tag,
					style,
					className: className,
					_key: 0,
                    ...on,
					...props,
                    ...otherOptions,
					children
				}]
                if (hasOptions) {
                    children = (h) => {
                        return options.map((item, index) => {
                            return h(resolveComponent(tag), {
                                ...item,
                                label: item.value,
                                size: item.size || "small",
                            }, item.label);
                        });
                    }
                    let parentTag = tag + "Group";
                    console.log(tag, parentTag);
                    result = [{
                        tag: parentTag,
                        style,
                        className: className,
                        _key: 0,
                        ...on,
                        ...props,
                        ...otherOptions,
                        children
                    }];
                }
                return result;
            }
			// 	return hasOptions ? options.map((item, index) => {
            //         let attrs = { ...props, ...item };
			// 		let _on = on;
			// 		if (item.key) {
            //             // console.log(234234234,this.formData,item.key,this.formData[item.key])
            //             attrs.modelValue = this.formData[item.key];
            //             // on["onUpdate:modelValue"] = val => this.setFormData(key, val);
            //             // _on = { ...on, input: val => this.setFormData(item.key, val) };
			// 		}
            //         console.log({
			// 			tag,
			// 			style,
			// 			className: className,
			// 			_key: index,
            //             ..._on,
            //             ...otherOptions,
			// 			...attrs,
			// 			children
			// 		})
			// 		return {
			// 			tag,
			// 			style,
			// 			className: className,
			// 			_key: index,
            //             ..._on,
            //             ...otherOptions,
			// 			...attrs,
			// 			children
			// 		}
			// 	}) : [{
			// 		tag,
			// 		style,
			// 		className: className,
			// 		_key: 0,
            //         ...on,
			// 		...props,
            //         ...otherOptions,
			// 		children
			// 	}]
            // }

            if(tag === 'Select' ){
                props = Object.assign({ clearable: true ,filterable:true}, props, {
					modelValue: this.formData[key]
				});
                if (hasOptions) {
                    children = () => {
                        return options.map((item,index) => {
                            if (item === null || typeof item !== 'object') {
                                item = { value: item, label: item, key:index }
                            }
                            return h(resolveComponent("Option"), { ...item } );
                        });
                }}
            };
			let aItem;
			if(tag == 'Select'){
				aItem = [{
					tag: tag || "Input",
					style,
					class: className,
					_key: key,
					...on,
					...props,
					...otherOptions,
					children
				}];
			}else{
				aItem = [{
					tag: tag || "Input",
					style,
					class: className,
					_key: key,
					...on,
					...props,
					...otherOptions,
					children
				}];
			}
			return aItem
		},
		async validate() {
            let bool = true;
			await this.$refs.form.validate(valid => {
                bool = valid;
            });
			if (!bool) {
				this.$Message.warning(this.$ct('global.common.fill_required'));
				return Promise.reject(false);
			}
			return true;
		},
		resetValidate() {
			this.$refs.form.resetValidate();
		},
        resetFields () {
            this.$refs.form.resetFields();
        },
	}
};
</script>
